package com.mar.quarkus.resource;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.crypto.SecureUtil;
import com.mar.quarkus.constants.DelFlag;
import com.mar.quarkus.model.PageResponse;
import com.mar.quarkus.model.SysRoleModel;
import com.mar.quarkus.model.SysUserModel;
import com.mar.quarkus.model.SysUserRoleModel;
import io.quarkus.hibernate.orm.panache.PanacheQuery;
import io.quarkus.panache.common.Page;
import io.quarkus.panache.common.Parameters;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;

import javax.annotation.security.RolesAllowed;
import javax.transaction.Transactional;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Objects;

import static java.util.stream.Collectors.toList;

/**
 * Description: 用户管理$ .<br>
 *
 * @author m-xy
 *     Created By 2020/4/27 14:24
 */
@Tag(name = "系统用户管理")
@Path("/sys/user")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class SysUserResource {

    @GET
    @Operation(summary = "查询记录列表")
    public PageResponse<SysUserModel> list(
        @QueryParam("key") String key,
        @QueryParam("index") int index,
        @QueryParam("size") int size
    ) {
        StringBuilder sql = new StringBuilder("delFlag = :delFlag ");
        Parameters parameters = Parameters.with("delFlag", DelFlag.LIVE.getCode());
        if (Objects.nonNull(key)) {
            sql.append("and userName like :userName ");
            parameters.and("userName", "%" + key + "%");
        }
        PanacheQuery<SysUserModel> query = SysUserModel.find(sql.toString(), parameters);
        query.page(Page.of(index, size == 0 ? 10 : size));
        List<SysUserModel> list = query.list();
        list.forEach(sysUserModel -> sysUserModel.password = null);
        long count = query.count();
        return PageResponse.page(count, list);
    }

    @GET
    @Path("/{id}")
    @Operation(summary = "查询记录")
    public SysUserModel findOne(@PathParam("id") Long id) {
        SysUserModel model = SysUserModel.findById(id);
        if (Objects.nonNull(model)) {
            model.password = null;
            List<SysUserRoleModel> list = SysUserRoleModel.find("userId", id).list();
            model.roleIds = list.stream().map(s -> s.roleId).collect(toList());
        }
        return model;
    }

    @DELETE
    @Path("/{id}")
    @RolesAllowed("admin")
    @Operation(summary = "逻辑删除记录")
    @Transactional(rollbackOn = Exception.class)
    public Response delete(@PathParam("id") Long id) {
        Assert.notNull(id);
        SysRoleModel model = SysRoleModel.findById(id);
        Assert.notNull(model);
        model.delFlag = DelFlag.DELETED.getCode();
        return Response.ok().build();
    }

    @POST
    @RolesAllowed("admin")
    @Operation(summary = "新增记录")
    @Transactional(rollbackOn = Exception.class)
    public Response save(@RequestBody SysUserModel sysUserModel) {
        List<SysUserModel> models = SysUserModel.find("userName", sysUserModel.userName).list();
        if (CollectionUtil.isNotEmpty(models)) {
            if (models.stream().anyMatch(u -> DelFlag.LIVE.getCode().equals(u.delFlag))) {
                throw new RuntimeException("用户账号已存在");
            }
        }
        sysUserModel.password = SecureUtil.sha256(sysUserModel.password);
        sysUserModel.persist();
        saveUserRoles(sysUserModel);
        return Response.ok().build();
    }

    /**
     * 保存用户角色信息.
     *
     * @param sysUserModel
     */
    private void saveUserRoles(SysUserModel sysUserModel) {
        if (CollectionUtil.isNotEmpty(sysUserModel.roleIds)) {
            sysUserModel.roleIds.forEach(roleId -> {
                SysUserRoleModel sysUserRoleModel = new SysUserRoleModel();
                sysUserRoleModel.userId = sysUserModel.id;
                sysUserRoleModel.roleId = roleId;
                sysUserRoleModel.persist();
            });
        }
    }

    @PUT
    @RolesAllowed("admin")
    @Operation(summary = "修改记录")
    @Transactional(rollbackOn = Exception.class)
    public Response update(@RequestBody SysUserModel sysUserModel) {
        Assert.notNull(sysUserModel.id);
        SysUserModel model = SysUserModel.findById(sysUserModel.id);
        BeanUtil.copyProperties(sysUserModel, model, "id", "password");
        SysUserRoleModel.delete("userId", sysUserModel.id);
        saveUserRoles(sysUserModel);
        return Response.ok().build();
    }
}
